#include <retro.h>
#include "player.h"
#include "player.hittest.h"

#define HITTEST_THRESHOLD   4

using namespace Retro::Player;
using namespace Retro::Player::Graphic;
using namespace Retro::Player::HitTest;

VOID HitTest::HitTestBounds(
  const Geom::Bounds& iSource,
  const Geom::Bounds& iTarget,
  HitTestData& ioData)
{
  Geom::Bounds  wDest = iSource;
  Geom::Bounds  wPath = iSource;

  ioData.dirX = DirectionNone;
  ioData.dirY = DirectionNone;
  ioData.dist = abs(iSource.x - iTarget.x) + abs(iSource.y - iTarget.y);

  wDest.point.x += (LONG)(ceilf(abs(ioData.vel.x)) *
    (ioData.vel.x < 0 ? -1 : 1));
  wDest.point.y += (LONG)(ceilf(abs(ioData.vel.y)) *
    (ioData.vel.y < 0 ? -1 : 1));

  if (ioData.hit = wPath.setUnion(wDest).intersects(iTarget))
  {
    if (ioData.vel.y > 0 &&
      iSource.y + wDest.cy - HITTEST_THRESHOLD < iTarget.y &&
      wPath.getBottom() + HITTEST_THRESHOLD > iTarget.y &&
      wPath.y - HITTEST_THRESHOLD < iTarget.y)
    {
      ioData.vel.y = (REAL)(iTarget.y - wDest.cy) - iSource.y;
      ioData.dirY = DirectionUp;
    }
    else if (ioData.vel.y < 0 &&
      iSource.y + HITTEST_THRESHOLD >= iTarget.getBottom() &&
      wPath.y - HITTEST_THRESHOLD <= iTarget.getBottom() &&
      wPath.getBottom() + HITTEST_THRESHOLD >= iTarget.getBottom())
    {
      ioData.vel.y = (REAL)iTarget.getBottom() - iSource.y;
      ioData.dirY = DirectionDown;
    }

    if (ioData.vel.x > 0 &&
      iSource.x + wDest.cx - HITTEST_THRESHOLD < iTarget.x &&
      wPath.getRight() + HITTEST_THRESHOLD > iTarget.x &&
      wPath.x - HITTEST_THRESHOLD < iTarget.x)
    {
      ioData.vel.x = (REAL)(iTarget.x - wDest.cx) - iSource.x;
      ioData.dirX = DirectionLeft;
    }
    else if (ioData.vel.x < 0 &&
      iSource.x + HITTEST_THRESHOLD >= iTarget.getRight() &&
      wPath.x - HITTEST_THRESHOLD <= iTarget.getRight() &&
      wPath.getRight() + HITTEST_THRESHOLD >= iTarget.getRight())
    {
      ioData.vel.x = (REAL)iTarget.getRight() - iSource.x;
      ioData.dirX = DirectionRight;
    }
  }
}
